/**
 * Runs and asserts data
 */


function TestEntryPoint($url, $alias) {
    
    this.alias = $alias;
    this.url   = $url;
    this.expected = {};
    this.in_data  = {};
    
    this.object = {};
    
    this.expectEqual = function($xpath, $value) {
        this.expected[$xpath] = $value;
    }
    
    this.expectInData = function($data) {
        this.in_data = $data;
    }
    
    this.assertInData = function() {
        
        if (this.in_data==null) {
            return; // break here
        }
        
        console.log('In data:');
        var $c = 0;
        var $m = 0;
        
        $results = this.xpath('/result', this.object);
        
        for ($i in $results) {
            $id = $results[$i]['id'];
            if (null!=this.in_data[$id] && this.in_data[$id]==$results[$i]['title']) {
                console.log('  - Found match, id='+$id+', title='+$results[$i]['title']);
                ++$m;
            }
            ++$c;
        }
        
        if ($m==this.in_data['count']) {
            console.log('PASSED: Found maching number of expected pairs title/id: '+$m);
        }
        
        if ($c==0) {
            console.log('No assertions defined');
        }
    }
    
    this.assert = function() {
        var $xpath  = '';
        var $value  = '';
        var $expct  = '';
        var $label  = '';
        var $object = this.object;
        console.log('-- Unit test for: ['+this.alias+'] -------------------------------');
        console.log('Entry point URL: '+this.url);
        console.log('Primitives:');
        for ($xpath in this.expected) {
            $expct = this.expected[$xpath];
            $value = this.xpath($xpath, $object);
            $label = ($value==$expct) ? 'PASSED' : 'FAILED';
            console.log($label+': Expected: ('+$expct+'), Returned: ('+$value+') - xpath: '+$xpath);
        }
        this.assertInData();
        console.log('-- Remote object returned: ');
        console.log(this.object);
        console.log('-------------------------------------------------------------');
    }
    
    this.run = function() {
        var $jqxhr = $.ajax({ 
            'url'      : this.url,
            'settings' : {
                'timeout' : 12000
            }
        }).done(function() { 
            
        }).fail(function() { 
            console.log('XHR query broke');
        }).always(function($data) { 
            /*** beacuse of scope issues we need to use this pattern below ***/
            $ob = new TestEntryPoint('', '');
            var $assert = Reg.instance().get($data.meta.request.entity, $data);
            $assert.setResponse($data);
            return;
        });
        return $jqxhr;        
    }
    
    this.setResponse = function($obj) {
        
        if (null!=$obj) {
            this.object = $obj;
            this.assert();           
        }
        return this;
    }
    
    this.xpath = function($xpath, $ob) {

        var $data    = (null==$ob) ? this.data : $ob;
        var $_return = null;
        var $_values = new Array();
        $_values[0]  = 'void';
        var $_key    = null;
        var $_err    = 0;
        var $xp      = new String($xpath);
        var $el      = $xp.split('/');
        if ($el[0]!=null && $el[0]=="") {$el.splice(0, 1);} // 1st removed
        //console.log($data);
        //console.log($el);
        for ($i=0; $i<$el.length; $i++) {
            $_key = $el[$i];
            //console.log($_key);
            $_values[$i+1] = ($i==0) ? $data[$_key] : (($_values[$i]!=null && $_values[$i][$_key]!=null) ? $_values[$i][$_key] : null);
        }
        return $_values[$el.length];
        
    }    
    
}

